package com.example.springstudy.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.springstudy.dao.dbo.DeptDbo;
import com.example.springstudy.dao.dto.DeptDto;
import com.example.springstudy.entity.Dept;
import com.example.springstudy.mapper.DeptMapper;
import com.example.springstudy.service.DeptService;
import com.example.springstudy.utils.DateUtils;
import com.example.springstudy.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

@Service
public class DeptServiceImp extends ServiceImpl<DeptMapper, Dept> implements DeptService {

    @Autowired
    DeptMapper deptMapper;

    @Override
    public List<DeptDbo> allDept() {
        List<Dept> list = this.list(new LambdaQueryWrapper<Dept>().eq(Dept::getIsDeleted, 0));
        return parseAllDept(list);
    }

    @Override
    public boolean addOrUpdateDept(DeptDto deptDto) {
        Dept dept = new Dept(deptDto);
        if(deptDto.getId() == null || deptDto.getId() == 0) {
            dept.setCreateBy(SecurityUtils.getUserId());
            dept.setCreateTime(DateUtils.defaultDate());
        } else {
            dept.setUpdateBy(SecurityUtils.getUserId());
        }
        return this.saveOrUpdate(dept);
    }

    @Override
    public boolean deleteDept(Integer id) {
        Dept dept = new Dept();
        dept.setId(id);
        dept.setUpdateBy(SecurityUtils.getUserId());
        dept.setIsDeleted(1);
        return this.updateById(dept);
    }

    @Override
    public List<Dept> listDept(Integer pageNum, Integer pageSize) {
        IPage<Dept> page = new Page<>(pageNum, pageSize);
        return this.list(page, new LambdaQueryWrapper<Dept>().orderByDesc(Dept::getCreateTime));
    }

    @Override
    public Dept findOne(int id) {
        return this.getOne(new LambdaQueryWrapper<Dept>().eq(Dept::getId, id));
    }

    private List<DeptDbo> parseAllDept(List<Dept> list) {
        Set<Integer> allIds = list.stream()
                .map(Dept::getId)
                .collect(Collectors.toSet());

        // 获取所有父级ID
        Set<Integer> parentIds = list.stream()
                .map(Dept::getParentId)
                .collect(Collectors.toSet());

        List<Integer> rootIds = parentIds.stream()
                .filter(id -> !allIds.contains(id))
                .toList();
        return rootIds.stream()
                .flatMap(rootId->buildDeptTree(rootId, list).stream())
                .collect(Collectors.toList());
    }

    private List<DeptDbo> buildDeptTree(Integer parentId, List<Dept> list) {
        return list.stream()
                .filter(dept-> Objects.equals(dept.getParentId(), parentId))
                .map(entity->{
                    DeptDbo deptDbo = new DeptDbo(entity);
                    List<DeptDbo> children = buildDeptTree(entity.getId(), list);
                    deptDbo.setChildren(children);
                    return deptDbo;
                }).toList();
    }
}
